/*
-----------------------------------------------------------------------------
This file is part of NxGraphics, Multimedia Engine.
Author : Stephane Kyles. Developed in Prague, Czech Republic.
				_   __       ____               _           
			   / | / /_  __ / __ \ ___  _   __ (_)_____ ___ 
			  /  |/ /| |/_// / / // _ \| | / // // ___// _ \
			 / /|  /_>  < / /_/ //  __/| |/ // // /__ /  __/
			/_/ |_//_/|_|/_____/ \___/ |___//_/ \___/ \___/ 
			                                                
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#ifndef __NXDEVICEHARDWARE_H__
#define __NXDEVICEHARDWARE_H__

#include "NxDevice_Prerequisites.h"

namespace NxDevice_Namespace {

enum NxDevice_Hardware_Types
{ 
	NXDEVICE_MIDI_CONTROLLER,
	NXDEVICE_WIIMOTE,
	NXDEVICE_3DCONNEXION,
	NXDEVICE_TRACKIR,
	NXDEVICE_DMX,
	NXDEVICE_MOUSE_KEYBOARD,
	NXDEVICE_MOCAP_MYSQL_READER ,
	NXDEVICE_MOCAP_MYSQL_RECORDER,
	NXDEVICE_AUDIO,
	NXDEVICE_WAVERIDER,
	NXDEVICE_OSC,
	NXDEVICE_LASER
} ;

enum NxDevice_Hardware_SubTypes
{ 
	NXDEVICE_SUB_MIDI_IN,
	NXDEVICE_SUB_MIDI_OUT,
	NXDEVICE_SUB_MIDI_THRU,
	NXDEVICE_SUB_SOCKET_MOCAP,
	NXDEVICE_SOUND_INPUT ,
	NXDEVICE_SOUND_OUTPUT ,
	NXDEVICE_SUB_OSC_RECEIVER ,
	NXDEVICE_SUB_OSC_SENDER,
	NXDEVICE_SUB_DMX_IN,
	NXDEVICE_SUB_DMX_OUT,
	NXDEVICE_SUB_OSC_KALYPSO

} ;

typedef struct DeviceHardwareParam
{
	std::string ParamName;
	int Datatype;
	double MinValue;
	double MaxValue;
	double CurrentValue;
} DeviceHardwareParam;

typedef struct DeviceHardwareMidiParam : public DeviceHardwareParam
{
	int Command;
	int Channel;
	int Note;
	int Velocity ;
};

class NxDevice_Export NxDevice_Hardware  
{
public :
	NxDevice_Hardware();
	~NxDevice_Hardware();
	virtual bool loadPropertySheet();
	virtual bool SavePropertySheet();
	virtual void BuildParamDictionary();
	virtual bool ConnectDevice() = 0;
	virtual bool DisconnectDevice() = 0;
	virtual void SetDeviceIndex( int Index );
	virtual int GetDeviceIndex();
	void GenerateID();
	unsigned long GetID();
	void SetID( unsigned long Id ) ;
	
	NxDevice_Hardware_Types GetHardwareDeviceType();
	void SetHardwareDeviceType( NxDevice_Hardware_Types Type);
	NxDevice_Hardware_SubTypes GetHardwareDeviceSubType();
	void SetHardwareDeviceSubType( NxDevice_Hardware_SubTypes SubType );
	std::string GetHardwareDeviceName();
	void SetHardwareDeviceName( std::string );
	std::list<std::string> GetParameterDictionaryPageList();
	typedef std::map< std::string, std::list< DeviceHardwareParam * > > DeviceHardwareParamType  ;
	DeviceHardwareParamType GetParameterDictionary();

	std::list< DeviceHardwareParam *> GetParameterDictionaryPage( std::string Page  );
	DeviceHardwareParam * GetParameterDictionaryParameter( std::string DictionaryName, long Index );

	virtual bool StartListening( int port );
	virtual bool StopListening();
	bool IsListening();
	unsigned long DeviceID  ;

protected :
	NxDevice_Hardware_Types mDeviceType ;
	NxDevice_Hardware_SubTypes mDeviceSubType;
	int mDeviceIndex;
	std::string mDeviceName;

	DeviceHardwareParamType DeviceHardwareParamList ;
	bool Thread_Should_Run;
	bool Listening ;
	int ListeningPort ;
};


enum NxDeviceOscValueType
{
	TYPEBOOL,
	TYPEFLOAT
};

class NxDevice_Export NxDeviceOscMessageValue
{
public:
	NxDeviceOscMessageValue();
	virtual ~NxDeviceOscMessageValue();
	NxDeviceOscValueType GetType();
	bool IsBool() const ;
	bool IsFloat() const;
 
	bool AsBool() const;
	float AsFloat() const;


protected :
	NxDeviceOscValueType mType;
	const char * mValue;
};

class NxDevice_Export NxDeviceOscMessageValueBool : public NxDeviceOscMessageValue
{
public :
	explicit NxDeviceOscMessageValueBool( bool );
};

class NxDevice_Export NxDeviceOscMessageValueFloat : public NxDeviceOscMessageValue
{
public :
	explicit NxDeviceOscMessageValueFloat( float );
};

class NxDevice_Export NxDeviceOscMessages
{
public :
	NxDeviceOscMessages( const char *, unsigned long );
	~NxDeviceOscMessages();
	const unsigned long GetNumArguments() const;
	const char * GetPattern() const;
	void AddArgument( bool Val );
	void AddArgument( float Val );
	typedef std::vector<NxDeviceOscMessageValue> MessageType;
	MessageType::const_iterator ArgumentsBegin() const;
	MessageType::const_iterator ArgumentsEnd() const;
private :
	const char * mPattern;
	unsigned long mNumArguments;
	MessageType mValues;
};

class NxDevice_Export NxDeviceOsc : public NxDevice_Hardware 
{
public :
	NxDeviceOsc();
	~NxDeviceOsc();
	bool loadPropertySheet();
	bool SavePropertySheet();
	bool ConnectDevice();
	bool DisconnectDevice();
	bool StartListening( int port );
	bool StopListening();
	void SendOscMessage( const char * ipAddress, NxDeviceOscMessages Message );
	NxDeviceOscListener * mOsc;
};

class NxDevice_Export NxDeviceDmx : public NxDevice_Hardware
{
public :
	NxDeviceDmx();
	~NxDeviceDmx();
	bool loadPropertySheet();
	bool SavePropertySheet();
	bool ConnectDevice();
	bool DisconnectDevice();
	void SendMessage( const unsigned int Channel, const unsigned char Value );
	void SetGrandMaster( const unsigned char Level );
	bool IsOpenDmxPro();
	static int GetNumDevices();
	NxDeviceDmxUtil * mDevice;
};

class NxDevice_Export Nx3DConnexion : public NxDevice_Hardware
{
public :
	Nx3DConnexion();
	~Nx3DConnexion();
	bool ConnectDevice();
	bool DisconnectDevice();
	void BuildParamDictionary();
	void SetLed( bool value );
	NxDevice3DConnexionInst * mDevice;

	enum Nx3DConnexionMask
	{
		LEFT	= 0x0001,
		RIGHT	= 0x0002,
		ALL		= LEFT|RIGHT
	};
};

 

class NxDevice_Export NxDeviceWiimote : public NxDevice_Hardware
{
public :
	//! NxDeviceWiimote Class Constructor.
	NxDeviceWiimote();
	//! NxDeviceWiimote Class Deconstructor.
	~NxDeviceWiimote();
	//! load Property sheet.
	bool loadPropertySheet();
	//! save Property sheet.
	bool SavePropertySheet();
	//! Build Dictionary.
	void BuildParamDictionary();
	//! Connect Device.
	bool ConnectDevice();
	//! Disconnect Device.
	bool DisconnectDevice();
	//! Get Num Available Wiimotes.
	static int GetNumDevices();
	// Device.
	NxDeviceWiimoteInst * mDevice;
};





struct NxKvantDeviceInfo
{
	DWORD maxScanrate;
	DWORD minScanrate;
	DWORD maxNumOfPoints;
	char type[32];
};

struct NxLaserPoint
{
	WORD x;
	WORD y;
	BYTE colors[6];
};

class NxDevice_Export NxDeviceLaserKvant : public NxDevice_Hardware 
{
public :
	NxDeviceLaserKvant();
	~NxDeviceLaserKvant();
	bool loadPropertySheet();
	bool SavePropertySheet();
	bool ConnectDevice();
	bool DisconnectDevice();

	DWORD GetNumDevices();
	WCHAR * GetDeviceIdentifier( DWORD index );
	NxKvantDeviceInfo GetLaserDeviceInfo( DWORD index );
 
	HANDLE KvantThreadHandle;  
	friend DWORD ThreadKvant(LPVOID lpParameter);

	void SetScanRate( DWORD Scanrate );
	void SetNumPoints( DWORD NumPoints );
	void SendFrame( DWORD deviceIndex, BYTE * pData, DWORD numOfPoints, DWORD scanrate );
	void SendBlank( DWORD deviceIndex, WORD x, WORD y );

	KVANT::KvantLib * Laser ;
	DWORD maxScanrate;
	DWORD currentScanrate;
	DWORD minScanrate;
	DWORD maxNumOfPoints;
	std::string type;
	DWORD deviceCount;
};




 








} // namespace

#endif